home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / FIND.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  10KB  |  405 lines

  1. #include "pt.h"
  2.  
  3. void pascal
  4. /* XTAG:xyToPos */
  5. xyToPos(inRow, inCol, where, pos, wOut)
  6.     int *inRow, *inCol;
  7.     register int *where;
  8.     long *pos;
  9.     struct window **wOut;
  10. {
  11.     extern unsigned char msgBuffer[];
  12.     extern struct window *windowList;
  13.     extern int tabWidth;
  14.     extern int debug;
  15.     extern int menuLine;
  16.     extern int scrRows, scrCols;
  17.  
  18.     register struct window *w;
  19.     long cp, cp2;
  20.     int n, tabStop, rowsDown, iBuffer, iLine;
  21.     int row, col;
  22.     int doRowCache, eofFlag;
  23.     unsigned char ch, nullChar;
  24.     unsigned char far *firstByte;
  25.     unsigned char far *lastByte;
  26.  
  27. eofFlag = 0;
  28. row = *inRow;
  29. if( (menuLine > 0 && row == 0)
  30.  || (menuLine < 0 && row == (scrRows-1)) ) {
  31.     *where = TOPLINE;
  32.     *wOut = NULL;
  33.     return;
  34. }
  35. col = *inCol;
  36. w = windowList;
  37. do {
  38.     /* see if this screen coordinate is in this window */
  39.  
  40.     /* above this window? */
  41.     if( row < w->row1 )
  42.         continue;
  43.  
  44.     /* below this window? */
  45.     if( row > w->row2 )
  46.         continue;
  47.  
  48.     /* left of this window? */
  49.     if( col < w->col1 )
  50.         continue;
  51.  
  52.     /* right of this window? */
  53.     if( col > w->col2 )
  54.         continue;
  55.  
  56.     /* it is this window so return its address */
  57.     *wOut = w;
  58.  
  59.     /* on the upper border? */
  60.     if( row == w->row1 ) {
  61.         if( col == w->col1 )
  62.             *where = UPPERLEFT;
  63.         else if( w->col2 == col )
  64.             *where = UPPERRIGHT;
  65.         else
  66.             *where = UPPERBORDER;
  67.     }
  68.     /* one the lower border? */
  69.     else if( row == w->row2 ) {
  70.         if( col == w->col1 )
  71.             *where = LOWERLEFT;
  72.         else if( col == w->col2 )
  73.             *where = LOWERRIGHT;
  74.         else
  75.             *where = LOWERBORDER;
  76.     }
  77.     /* on the left border? */
  78.     else if( col == w->col1 )
  79.         *where = LEFTBORDER;
  80.     /* on the right border? */
  81.     else if( col == w->col2 )
  82.         *where = RIGHTBORDER;
  83.     /* else it must be inside */
  84.     else {
  85.         *where = INSIDEWINDOW;
  86.         rowsDown = row - w->row1 - 1;    /* rows down */
  87.         /* has window moved since we last found a line? */
  88.         doRowCache = 1;
  89.         if( w->lastPosTop == w->posTopline ) {
  90.             /* if so find the new line relative to it */
  91.             cp = w->posCurLast;
  92.             rowsDown -= w->rowCurLast;
  93.             if( rowsDown < 0 ) {
  94.                 rowsDown = -rowsDown;
  95.                 cp=prevLine(w->fileId,cp,&rowsDown);
  96.             } else if( rowsDown > 0 )
  97.                 goto countDown;
  98.         } else {
  99.             /* just count down from the top line */
  100.             cp = w->posTopline;
  101.         countDown:
  102.             n = rowsDown;
  103.             cp = nextLine(w->fileId, cp, &rowsDown);
  104.             /* fix so that EOF works */
  105.             if( (n -= rowsDown) > 0 ) {
  106.                 *inRow -= n;
  107.                 doRowCache = 0;
  108.             }
  109.             /* see if EOF on a line alone */
  110.             if( (cp-1) > 0 &&
  111.               readChar(w->fileId,cp-1)!='\n') {
  112.                 /* another fix so EOF works */
  113.                 --*inRow;
  114.                 doRowCache = 0;
  115.             }
  116.         }
  117.         /* if we are near end of file, "row" and the */
  118.         /* "cp" will not really be right.  The +3 is */
  119.         /* superstitious but I want to be sure we don't get */
  120.         /* get off on the counts.  There is little need */
  121.         /* to optimize at the end of the file, we can forgo */
  122.         /* that to be safe */
  123.         if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
  124.             /* compute the number of rows down */
  125.             w->rowCurLast = row - w->row1 - 1;
  126.             w->posCurLast = cp;
  127.             w->lastPosTop = w->posTopline;
  128.         } else
  129.             w->lastPosTop = -1;
  130.         n = col - w->col1 - 1 + w->indent;
  131.         iBuffer = 0;
  132.         iLine = 0;
  133.         firstByte = (unsigned char far *)1;
  134.         lastByte = (unsigned char far *)0;
  135.         cp2 = cp;
  136.         while( iLine <= n ) {
  137.             if( firstByte > lastByte ) {
  138.                   if(getSpan(w->fileId, cp2, &firstByte,
  139.                               &lastByte, 0) ) {
  140.                        nullChar = 0;
  141.                        eofFlag = 1;
  142.                        firstByte = &nullChar;
  143.                        lastByte = firstByte;
  144.                   }
  145.                 }
  146.                 ++cp2;
  147.             ++iBuffer;
  148.             ch = *firstByte++;
  149.             switch( ch ) {
  150.             case '\n':    /* end of line */
  151.                 goto endLoop;
  152.             case 0:    /* end of file */
  153.                 if( eofFlag )
  154.                     goto endLoop;
  155.                 else
  156.                     goto justACharacter;
  157.             case '\t':
  158.                  tabStop = iLine + tabWidth
  159.                       - (iLine % tabWidth);
  160.                 if( tabStop > n )
  161.                     goto endLoop;
  162.                 else
  163.                     iLine = tabStop;
  164.                 break;
  165.             case '\r':    /* ignore CRs */
  166.                 /* unless they are not followed */
  167.                 /* by a NL */
  168.                 if( *firstByte == '\n' )
  169.                     break;
  170.                 /* else drop through */
  171.             default:
  172.             justACharacter:
  173.                 iLine++;
  174.                 break;
  175.             }
  176.         }
  177.     endLoop:
  178.         *pos = cp + iBuffer - 1;
  179.     }
  180.     return;
  181. } while( (w = w->nextWindow) != NULL );
  182.  
  183. *where = OUTSIDEWINDOW;
  184. *wOut = NULL;
  185. }
  186.  
  187. long pascal
  188. /* XTAG:xyToWindow */
  189. xyToWindow(w, inRow, inCol)
  190.     register struct window *w;
  191.     int *inRow, *inCol;
  192. {
  193.     extern unsigned char msgBuffer[];
  194.     extern unsigned char textBuffer[];
  195.     extern struct window *windowList;
  196.     extern int tabWidth;
  197.     extern int debug;
  198.  
  199.     long cp, cp2;
  200.     int n, tabStop, rowsDown, iBuffer, iLine;
  201.     int row, col;
  202.     int doRowCache, eofFlag;
  203.     unsigned char ch, nullChar;
  204.     unsigned char far *firstByte;
  205.     unsigned char far *lastByte;
  206.  
  207.     eofFlag = 0;
  208.     row = *inRow;
  209.     col = *inCol;
  210.     /* handle the cases where the cursor is outside of the window */
  211.     /* return the nearest character in the window */
  212.     /* if above or below, use the nearest line */
  213.     if( row <= w->row1 )
  214.         row = w->row1 + 1;
  215.     else if( row >= w->row2 )
  216.         row = w->row2 - 1;
  217.     /* if to the side, use the nearest column */
  218.     if( col <= w->col1 )
  219.         col = w->col1 + 1;
  220.     else if( col >= w->col2 )
  221.         col = w->col2 - 1;
  222.  
  223.     /* now find the character position in the file */
  224.     rowsDown = row - w->row1 - 1;
  225.         /* rows down from the top line displayed in the window */
  226.     doRowCache = 1;
  227.     /* Has the window text moved since we last found a line? */
  228.     if( w->lastPosTop == w->posTopline ) {
  229.         /* if so find the new line relative to it */
  230.         cp = w->posCurLast;
  231.         rowsDown -= w->rowCurLast;
  232.             /* adjust rows down by where the cached line is */
  233.         if( rowsDown < 0 ) {
  234.             /* line to find is above the cached line */
  235.             rowsDown = -rowsDown;
  236.             cp = prevLine(w->fileId, cp, &rowsDown);
  237.         } else if( rowsDown > 0 )
  238.             /* line to find is below the cached line */
  239.             goto countDown;
  240.             /* count down the lines from the cached line */
  241.     } else {
  242.         /* if not, just count down from the top line */
  243.         cp = w->posTopline;
  244.     countDown:
  245.         n = rowsDown;    /* remember how many we asked to count down */
  246.         cp = nextLine(w->fileId, cp,
  247.                 &rowsDown);
  248.         /* fix so that EOF works */
  249.             /* rowsDown is how many nextLine actually went down */
  250.             /* if n > rowsDown then we hit EOF */
  251.         if( (n -= rowsDown) > 0 ) {
  252.             /* tell the caller the hit was below the last line */
  253.             *inRow -= n;
  254.             doRowCache = 0;
  255.         }
  256.         /* see if the EOF marker NOT is on a line alone */
  257.         /* this will be try if nextLine stopped at the EOF marker */
  258.         /* and the last real character is NOT a newline */
  259.         /* The first test is a fix when you are at the beginning */
  260.         /* of the file */
  261.         if( cp != 0L && readChar(w->fileId, cp-1) != '\n' ) {
  262.             /* another fix so that EOF works */
  263.             --*inRow;
  264.             doRowCache = 0;
  265.         }
  266.     }
  267.     /* if we are near the end of file the "row" and the "cp" */
  268.     /* will not really be right.  The +3 is superstitious but */
  269.     /* I want to be sure we don't get off on the counts.  There */
  270.     /* is little need to optimize at the end of the file, we */
  271.     /* can forgo that to be safe */
  272.     if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
  273.         w->rowCurLast = row - w->row1 - 1;    /* rows down */
  274.         w->posCurLast = cp;
  275.         w->lastPosTop = w->posTopline;
  276.     } else
  277.         w->lastPosTop = -1;
  278.  
  279.     /* figure out the physical column */
  280.     n = col - w->col1 - 1 + w->indent;
  281.  
  282.     /* now we have to figure out the text file position  by */
  283.     /* reconstructing the line */
  284.     iBuffer = 0;
  285.     iLine = 0;
  286.     firstByte = (unsigned char far *)1;
  287.     lastByte = (unsigned char far *)0;
  288.     cp2 = cp;
  289.     while( iLine <= n ) {
  290.         if( firstByte > lastByte ) {
  291.             if(getSpan(w->fileId, cp2, &firstByte, &lastByte,0)){
  292.                  nullChar = 0;
  293.                  eofFlag = 1;
  294.                  firstByte = &nullChar;
  295.                  lastByte = firstByte;
  296.             }
  297.         }
  298.         ++cp2;
  299.         ++iBuffer;
  300.         ch = *firstByte++;
  301.         switch( ch ) {
  302.         case '\n':    /* end of line */
  303.             goto endLoop;
  304.         case 0:    /* end of file */
  305.             if( eofFlag )
  306.                 goto endLoop;
  307.             else
  308.                 goto justACharacter;
  309.         case '\t':
  310.             tabStop = iLine + tabWidth - (i